import * as THREE from 'three';
import {HydrodynamicData,HydrodynamicDataWithIndex,WaterQualityDataWithIndex,WaterDataWithIndex
    ,Point,Point2D,
} from './hydroData';
import { CreateGeometryMesh,CreateGeometryMeshWithColor,
    CreateGeometry,CreateGeometryWithColor, CreateGeometryWithUV,CreateGeometryWithColor4,
    createCubeMesh,CreateSphereMesh
} from './createModel';

import { Value2Color,Value2ColorTenSegements,Value2ColorBlueGreenYellowRedWithFixWQRValue } from './dealPropertyValue'
import { CreateImayerFromData,CalculateUVArray } from './createImageTexture';

import TextureMapperImager from '@/assets/uv_grid_opengl.jpg';


const IMGSIZE = 128;

// TODO:构建三维水体模型并添加颜色材质，需要调整显示的颜色效果
export function ParseDATFromFileContent(fileContent:string){

    // 去掉首行无用数据
    const lines = fileContent.split('\n').slice(2); // 假设前两行是标题和表头，从第三行开始读取数据
    // console.log('读取的数据第一行:', lines[0]);

    // TODO:读取更加精细的水文界面顶点数据来建模，进行细分，左右两岸+中间3个
    // .--x--x--x--.
    //  \  \  \  \  \
    //   .--x--x--x--.

    let leftHydroData:  Array<HydrodynamicData> = [];
    let rightHydroData:  Array<HydrodynamicData> = [];

    let count_num = 0;
    lines.forEach(line => {
        if (line.trim() === '') return; // 跳过空行
    
        const values = line.split(/\s+/).map(value => value.trim());
        // console.log('values:', values);
        count_num++;
    
        // 文件中的数据格式严格按照提供的格式，每个字段依次对应
        const [
            , I, J, level, totalFlux, waterLevel, waterDepth, USpeed, VSpeed, WSpeed, flux, temperature, salinity, colorants, X, Y, Z, 
        ] = values;
    
        const hydrodynamicData = new HydrodynamicData(
            parseInt(I, 10),parseInt(J, 10),parseInt(level, 10),
            parseFloat(totalFlux),parseFloat(waterLevel),parseFloat(waterDepth),
            parseFloat(USpeed),parseFloat(VSpeed),parseFloat(WSpeed),
            parseFloat(flux),parseFloat(temperature),parseFloat(salinity),parseFloat(colorants),
            parseFloat(X),parseFloat(Y),parseFloat(Z)
        );

        // 读取dat中的数据
        if(count_num>=5 && count_num<=343){//河流水面最左侧
            if(count_num % 2 == 1){
                leftHydroData.push(hydrodynamicData);
            }
        }
        else if(count_num>=706 && count_num<=875){//河流水面最右侧
            rightHydroData.push(hydrodynamicData);
        }
        else{
            
        }

    });

    let geometry = CreateRiverCubeWithLeftRightPoint(leftHydroData,rightHydroData);

    // 创建记录值灰度图
    const texture = CreateImageryWithValue(leftHydroData, rightHydroData);
    // console.log(texture);

    // const texture = new THREE.TextureLoader().load(TextureMapperImager);

    const material = new THREE.MeshBasicMaterial({ 
        map: texture ,
        side: THREE.DoubleSide
    });

    const mesh = new THREE.Mesh(geometry, material);

    return mesh;
}

// NOTE:测试水体建模内容
function CreateRiverCubeWithLeftRightPoint(leftHydroData:Array<HydrodynamicData>,rightHydroData:Array<HydrodynamicData>):THREE.BufferGeometry{
    const originPoint = leftHydroData[0];
    // console.log("原点数据：", originPoint);

    const pointCount = leftHydroData.length;
    
    // 构建顶面数据
    let leftPointVertex = [];
    let rightPointVertex = [];

    // 构建底面数据
    let leftPointVertexDown = [];
    let rightPointVertexDown = [];

    // // 顶点颜色
    // let leftVertexColors = [];
    // let rightVertexColors = [];

    // NOTE:读取XYZ数据进行建模
    for(let i =0;i<pointCount;i++){

        // 取消相对于坐标原点的Z值差
        leftPointVertex.push(leftHydroData[i].X-originPoint.X, leftHydroData[i].Y-originPoint.Y, leftHydroData[i].Z);
        rightPointVertex.push(rightHydroData[i].X-originPoint.X, rightHydroData[i].Y-originPoint.Y, rightHydroData[i].Z);

        // leftPointVertex.push(leftHydroData[i].X-originPoint.X, leftHydroData[i].Y-originPoint.Y, leftHydroData[i].Z-originPoint.Z);
        // rightPointVertex.push(rightHydroData[i].X-originPoint.X, rightHydroData[i].Y-originPoint.Y, rightHydroData[i].Z-originPoint.Z);

        // z值需要获取改点的地形高度
        leftPointVertexDown.push(leftHydroData[i].X-originPoint.X, leftHydroData[i].Y-originPoint.Y, 0);
        rightPointVertexDown.push(rightHydroData[i].X-originPoint.X, rightHydroData[i].Y-originPoint.Y, 0);

        // // 计算顶点颜色
        // let lefPointColor = [1.0,0,0];
        // leftVertexColors.push(lefPointColor[0],lefPointColor[1],lefPointColor[2]);
        // let rightPointColor = [0,1.0,0,0];
        // rightVertexColors.push(rightPointColor[0], rightPointColor[1], rightPointColor[2]);
    }

    // 顶点数组
    let vertexArray = [...leftPointVertex, ...rightPointVertex, ...leftPointVertexDown, ...rightPointVertexDown];
    console.log("顶点数组：",vertexArray)
    console.log("顶点数组后长度：",vertexArray.length);//pointCount*3

    // let colorArray = [...leftVertexColors, ...rightVertexColors, ...leftVertexColors, ...rightVertexColors];
    // console.log("颜色数组长度：",colorArray.length);


    let indexArray = [];
    // 正面-构建起始点的面
    indexArray.push(
        getIndexLeftTop(0,pointCount),   getIndexRightTop(0,pointCount),  getIndexLeftDown(0,pointCount),
        getIndexLeftDown(0,pointCount),getIndexRightTop(0,pointCount),getIndexRightDown(0,pointCount)
    );

    // 侧面-构建中间的面
    for(let i=0;i<pointCount-1;i++){
        // FIXME:检查顶点索引记录情况
        indexArray.push(
            // 顶面索引顺序
            getIndexLeftTop(i,pointCount),   getIndexLeftTop(i+1,pointCount), getIndexRightTop(i,pointCount),
            getIndexLeftTop(i+1,pointCount), getIndexRightTop(i+1,pointCount),getIndexRightTop(i,pointCount),  
            
            // 底面索引顺序
            getIndexLeftDown(i,pointCount),   getIndexRightDown(i,pointCount),  getIndexLeftDown(i+1,pointCount),
            getIndexLeftDown(i+1,pointCount), getIndexRightDown(i,pointCount),  getIndexRightDown(i+1,pointCount),

            // 左侧面
            getIndexLeftTop(i,pointCount),  getIndexLeftDown(i,pointCount),   getIndexLeftTop(i+1,pointCount),
            getIndexLeftDown(i,pointCount), getIndexLeftDown(i+1,pointCount), getIndexLeftTop(i+1,pointCount),
            
            // 右侧面
            getIndexRightTop(i,pointCount),    getIndexRightTop(i+1,pointCount),   getIndexRightDown(i,pointCount),
            getIndexRightTop(i+1,pointCount),  getIndexRightDown(i+1,pointCount),  getIndexRightDown(i,pointCount)
        );
    }

    // i=pointCount-1
    // 背面-构建结束点的面
    indexArray.push(
        getIndexRightTop(pointCount-1,pointCount),   getIndexLeftTop(pointCount-1,pointCount),   getIndexRightDown(pointCount-1,pointCount),
        getIndexLeftTop(pointCount-1,pointCount),    getIndexLeftDown(pointCount-1,pointCount),  getIndexRightDown(pointCount-1,pointCount),
    );


    let halfUVArrays = CalculateUVArray(IMGSIZE,pointCount*2);
    let uvArrays = [...halfUVArrays, ...halfUVArrays];
    // console.log("uv数组：", uvArrays);
    // console.log("uv数组长度：", uvArrays.length);//pointCount*2



    // let geometry = CreateGeometry(new Float32Array(vertexArray), new Uint16Array(indexArray));
    let geometry = CreateGeometryWithUV(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(uvArrays));
    // let geometry = CreateGeometryWithColor(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(colorArray)); 

    return geometry;



    function getIndexLeftTop(i:number,pointCount:number){
        return i;
    }
    function getIndexLeftDown(i:number,pointCount:number){
        return 2*pointCount + i;
    }
    function getIndexRightTop(i:number,pointCount:number){
        return pointCount + i;
    }
    function getIndexRightDown(i:number,pointCount:number){
        return 3*pointCount + i;
    }
}

function CreateImageryWithValue(leftHydroData:Array<HydrodynamicData>,rightHydroData:Array<HydrodynamicData>){
    // 获取河流左右岸点的个数
    const pointCount = leftHydroData.length;
    
    // 获取河岸点上记录的值
    let leftPointValue = [];
    let rightPointValue = [];

    for(let i =0;i<pointCount;i++){
        // TODO:当前取的是温度作为展示内容，要将此处作为接口暴露出来
        leftPointValue.push(leftHydroData[i].temperature);
        rightPointValue.push(rightHydroData[i].temperature);
    }

    let valueArray = [...leftPointValue,...rightPointValue];

    let valueImagerArray = [];//需要与顶点数组保持一致
    for(let i=0;i<pointCount-1;i++){
        valueImagerArray.push(
            valueArray[i] ,  valueArray[i+1], valueArray[pointCount+i],//左岸点
            valueArray[i+1], valueArray[pointCount+i+1], valueArray[pointCount+i]//右岸点
        );
    }


    return CreateImayerFromData(IMGSIZE,valueImagerArray);
    
}



// 解析单层湖体DAT数据
export function ParseLakeDATFromFileContent(fileContent:string){
    // 去掉无用数据
    const lines = fileContent.split('\n').slice(2); //从第三行开始读取数据

    let lakeHydroData:Array<HydrodynamicDataWithIndex> = [];

    let count_num = 0;
    lines.forEach(line => {
        if (line.trim() === '') return; // 跳过空行
    
        const values = line.split(/\s+/).map(value => value.trim());
        // console.log('values:', values);

        count_num++;
    
        // 文件中的数据格式严格按照提供的格式，每个字段依次对应
        const [
            , I, J, level, totalFlux, waterLevel, waterDepth, USpeed, VSpeed, WSpeed, flux, temperature, salinity, colorants, X, Y, Z, 
        ] = values;
    
        const hydrodynamicData = new HydrodynamicDataWithIndex(
            count_num,
            parseInt(I, 10),parseInt(J, 10),parseInt(level, 10),
            parseFloat(totalFlux),parseFloat(waterLevel),parseFloat(waterDepth),
            parseFloat(USpeed),parseFloat(VSpeed),parseFloat(WSpeed),
            parseFloat(flux),parseFloat(temperature),parseFloat(salinity),parseFloat(colorants),
            parseFloat(X),parseFloat(Y),parseFloat(Z)
        );

        // console.log(`当前第${count_num}个点数据是${hydrodynamicData}`);

        // const LAKEPOINTCOUNT = 2124;
        // // 读取dat中的数据,可控制读取多少个
        // if(count_num <= LAKEPOINTCOUNT){
        //     lakeHydroData.push(hydrodynamicData);
        // }

        lakeHydroData.push(hydrodynamicData);
    });


    return lakeHydroData;

}


// 解析5层湖体的DAT数据
export function Parse5LevelLakeDATFromFileContent(fileContent:string){
    // 去掉无用数据
    const lines = fileContent.split('\n').slice(2); //从第三行开始读取数据

    let fiveLevelLakeHydroData:Array<Array<HydrodynamicDataWithIndex>> = [];
    let lakeHydroData:Array<HydrodynamicDataWithIndex> = [];

    let count_num = 0;
    lines.forEach(line => {
        if (line.trim() === '') return; // 跳过空行
    
        const values = line.split(/\s+/).map(value => value.trim());
        // console.log('values:', values);

        count_num++;
    
        // 文件中的数据格式严格按照提供的格式，每个字段依次对应
        const [
            , I, J, level, totalFlux, waterLevel, waterDepth, USpeed, VSpeed, WSpeed, flux, temperature, salinity, colorants, X, Y, Z, 
        ] = values;
    
        const hydrodynamicData = new HydrodynamicDataWithIndex(
            count_num,
            parseInt(I, 10),parseInt(J, 10),parseInt(level, 10),
            parseFloat(totalFlux),parseFloat(waterLevel),parseFloat(waterDepth),
            parseFloat(USpeed),parseFloat(VSpeed),parseFloat(WSpeed),
            parseFloat(flux),parseFloat(temperature),parseFloat(salinity),parseFloat(colorants),
            parseFloat(X),parseFloat(Y),parseFloat(Z)
        );

        // console.log(`当前第${count_num}个点数据是${hydrodynamicData}`);

        lakeHydroData.push(hydrodynamicData);
    });

    // NOTE:写死部分，只能针对洪湖网格2124个点进行处理
    const LAKEPOINTCOUNT = 2124;

    for(let i=0;i<lakeHydroData.length/LAKEPOINTCOUNT;i++){
        fiveLevelLakeHydroData.push(lakeHydroData.slice(i*LAKEPOINTCOUNT, (i+1)*LAKEPOINTCOUNT));
    }

    return fiveLevelLakeHydroData;

}

export function Parse5LevelLakeWQRDATFromFileContent(fileContent:string){
    const contentLines = fileContent.split('\n');
    // 去掉无用数据
    const lines = contentLines.slice(3); //从第四行？开始读取数据

    let fiveLevelLakeHydroData:Array<Array<WaterQualityDataWithIndex>> = [];
    let lakeHydroData:Array<WaterQualityDataWithIndex> = [];

    let count_num = 0;
    lines.forEach(line => {
        if (line.trim() === '') return; // 跳过空行
    
        // console.log("line:",line);
        const values = line.split(/\s+/).map(value => value.trim());
        // console.log('values:', values);

        count_num++;
    
        // 文件中的数据格式严格按照提供的格式，每个字段依次对应
        // I J 层次 CHC CHG CHD ROC LOC DOC ROP LOP DOP P4D RON LON CON NHX NOX SUU SAA COD DOX TAM FCB TN TP CODMN CHL ZMD X Y Z
        const [
            , I, J, level, CHC,CHG, CHD, ROC, LOC, DOC, ROP, LOP, DOP, P4D, RON, LON, CON, NHX, NOX, SUU, SAA, COD, DOX, TAM, FCB, TN, TP, CODMN, CHL, ZMD, X, Y, Z, 
        ] = values;
    
        const hydrodynamicData = new WaterQualityDataWithIndex(
            count_num,
            parseInt(I, 10),parseInt(J, 10),parseInt(level, 10),
            parseFloat(CHC),parseFloat(CHG),parseFloat(CHD),parseFloat(ROC),parseFloat(LOC),parseFloat(DOC),
            parseFloat(ROP),parseFloat(LOP),parseFloat(DOP),parseFloat(P4D),parseFloat(RON),parseFloat(LON),parseFloat(CON),
            parseFloat(NHX),parseFloat(NOX),parseFloat(SUU),parseFloat(SAA),parseFloat(COD),parseFloat(DOX),parseFloat(TAM),parseFloat(FCB),
            parseFloat(TN),parseFloat(TP),parseFloat(CODMN),parseFloat(CHL),parseFloat(ZMD),
            parseFloat(X),parseFloat(Y),parseFloat(Z)
        );

        // console.log(`当前第${count_num}个点数据是${hydrodynamicData}`);

        lakeHydroData.push(hydrodynamicData);
    });

    // NOTE:写死部分，只能针对洪湖网格2124个点进行处理
    const LAKEPOINTCOUNT = 2124;

    for(let i=0;i<lakeHydroData.length/LAKEPOINTCOUNT;i++){
        fiveLevelLakeHydroData.push(lakeHydroData.slice(i*LAKEPOINTCOUNT, (i+1)*LAKEPOINTCOUNT));
    }

    return fiveLevelLakeHydroData;

}



// 解析PLT文件数据，获取所有信息
export function parsePltFileGetDataArray(fileContent: string) : { [key: string]: number[] } {

    const lines = fileContent.split('\n');
    let variables: string[] = [];
    let numNodes: number | null = null;
    let numEdges: number | null = null;
    let valueArray: number[][] = [];
    let tmpArray: number[] = [];
    let indexArray: number[] = [];
    let blockData: { [key: string]: number[] } = {};

    for (let line of lines) {
        line = line.trim();
        if (line.startsWith("VARIABLES")) {
            // 提取变量名称
            variables = line.split('=')[1].replace(/"/g, '').trim().split(/\s+/);
        } else if (line.startsWith("N=")) {
            // 使用正则表达式来创建键值对，并过滤出N和E的值
            const values = {};
            line.split(',').forEach(part => {
                const [key, value] = part.split('=').map(item => item.trim());
                values[key] = value;
            });

            numNodes = parseInt(values['N'] || '0', 10); // 获取N的值，如果不存在则默认为0
            numEdges = parseInt(values['E'] || '0', 10); // 获取E的值，如果不存在则默认为0

            console.log(`PLT文件中顶点个数为${numNodes}，边的个数为${numEdges}`);

            break;
        }
    }

    // 定位到数据部分，DT下一行
    const dataStart = lines.findIndex(line => line.startsWith("DT=")) + 1;

    // 提取数据部分（过滤空行或不符合格式的行）
    const dataLines = lines.slice(dataStart).filter(
        line => line.trim() && !line.startsWith("ZONE")
    );

    const lineXPointCount = 10;

    // 处理每一行数据
    for (let line of dataLines) {
        try {
            const splitLine = splitAndTrim(line,' ');

            // 处理每一行的数据 X Y ZB U V W......
            if (splitLine.length !== lineXPointCount) {
                if (tmpArray.length) { // 只有当临时数组非空时才追加
                    tmpArray.push(...splitLine.map(Number));
                    valueArray.push(tmpArray);
                    tmpArray = [];
                    continue;
                }

                // 处理顶点索引问题，长度均为8
                if (valueArray.length === variables.length) {
                    if (splitLine.length === 8) {
                        indexArray.push(...splitLine.map(Number));
                    } else {
                        console.error("Error: The length of the index array is not 8.");
                        break;
                    }
                }
            } else {
                tmpArray.push(...splitLine.map(Number));
            }
        } catch (e) {
            continue;
        }
    }

    // 添加最后一块数据，如果有的话
    if (tmpArray.length) {
        valueArray.push(tmpArray);
    }

    // console.log("Variables:", variables);
    // console.log("Variables length:", variables.length);
    // console.log("valueArray length:", valueArray.length);

    // 确保 variables 和 valueArray 的长度一致
    if (variables.length === valueArray.length) {

        for(let i=0;i<variables.length;i++){
            blockData[variables[i]] = valueArray[i];
        }
        // console.log("Construct blockData.");
        
    } else {
        console.error("The number of variables does not match the number of data blocks.");
        return;
    }

    blockData.index = indexArray;
    // console.log("blockData",blockData);
    // console.log(`模型网格顶点个数为${blockData.X.length}`);

    return blockData;

}


export function parsePltFile2Threejs(fileContent: string) {

    const lines = fileContent.split('\n');
    let variables: string[] = [];
    let numNodes: number | null = null;
    let numEdges: number | null = null;
    let valueArray: number[][] = [];
    let tmpArray: number[] = [];
    let indexArray: number[] = [];
    let blockData: { [key: string]: number[] } = {};

    for (let line of lines) {
        line = line.trim();
        if (line.startsWith("VARIABLES")) {
            // 提取变量名称
            variables = line.split('=')[1].replace(/"/g, '').trim().split(/\s+/);
        } else if (line.startsWith("N=")) {
            // 使用正则表达式来创建键值对，并过滤出N和E的值
            const values = {};
            line.split(',').forEach(part => {
                const [key, value] = part.split('=').map(item => item.trim());
                values[key] = value;
            });

            numNodes = parseInt(values['N'] || '0', 10); // 获取N的值，如果不存在则默认为0
            numEdges = parseInt(values['E'] || '0', 10); // 获取E的值，如果不存在则默认为0

            break;
        }
    }

    // 定位到数据部分，DT下一行
    const dataStart = lines.findIndex(line => line.startsWith("DT=")) + 1;

    // 提取数据部分（过滤空行或不符合格式的行）
    const dataLines = lines.slice(dataStart).filter(
        line => line.trim() && !line.startsWith("ZONE")
    );

    const lineXPointCount = 10;

    // 处理每一行数据
    for (let line of dataLines) {
        try {
            const splitLine = splitAndTrim(line,' ');

            // 处理每一行的数据 X Y ZB U V W......
            if (splitLine.length !== lineXPointCount) {
                if (tmpArray.length) { // 只有当临时数组非空时才追加
                    tmpArray.push(...splitLine.map(Number));
                    valueArray.push(tmpArray);
                    tmpArray = [];
                    continue;
                }

                // 处理顶点索引问题，长度均为8
                if (valueArray.length === variables.length) {
                    if (splitLine.length === 8) {
                        indexArray.push(...splitLine.map(Number));
                    } else {
                        console.error("Error: The length of the index array is not 8.");
                        break;
                    }
                }
            } else {
                tmpArray.push(...splitLine.map(Number));
            }
        } catch (e) {
            continue;
        }
    }

    // 添加最后一块数据，如果有的话
    if (tmpArray.length) {
        valueArray.push(tmpArray);
    }

    // console.log("Variables:", variables);
    // console.log("Variables length:", variables.length);
    // console.log("valueArray length:", valueArray.length);

    // 确保 variables 和 valueArray 的长度一致
    if (variables.length === valueArray.length) {
        for(let i=0;i<variables.length;i++){
            blockData[variables[i]] = valueArray[i];
        }

        // console.log("Construct blockData.");
        
    } else {
        console.error("The number of variables does not match the number of data blocks.");
        return;
    }

    blockData.index = indexArray;
    // console.log("blockData",blockData);
    
    // let mesh = CreateMeshFromPLT(blockData);
    // return mesh; 

    
    // let geometry = CreateGeometryFromPLT(blockData);

    // let geometry = CreateGeometryFromPLTWithColor(blockData);

    let geometry = CreateFiveLevelGeometryFromPLT(blockData);
    return geometry;
}





function splitAndTrim(str: string, delimiter: string = ' '): string[] {
    // 使用正则表达式来匹配任意数量的空白字符
    return str.trim().split(new RegExp(`\\s*${delimiter}\\s*`))
                .filter(item => item.length > 0);
}

function CreateMeshFromPLT(blockData: { [key: string]: number[] }){
    let geometry = CreateGeometryFromPLT(blockData);

    // 创建双面可视的材质
    
    // 构建mesh并传出去
    const mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
        // vertexColors: true, // 启用顶点颜色
        color: 0xffffff, 
        // side: THREE.DoubleSide // 双面渲染
        // wireframe: true,
    }));

    return mesh;
}

export function CreateGeometryFromPLT(blockData: { [key: string]: number[] }) {


    const originPoint = [blockData.X[0], blockData.Y[0], blockData.ZB[0]]
    console.log("originPoint:", originPoint);


    let vertexArray = [];

    const pointCount = blockData.X.length;
    // const pointCount = 6;
    // 顶点数组
    for (let i = 0; i < pointCount; i++) {
        vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], blockData.ZB[i]-originPoint[2]);
    }

    // 索引数组
    let indexArray = [];

    const faceCount = blockData.index.length / 8;
    // const faceCount = 1;
    for (let i = 0; i < faceCount; i++) {
        // i为index每一行的内容

        indexArray.push(
            // 此三角形未使用。用于构建的是face2+face3
            //----
            // \ |
            //  \|
            // blockData.index[i*8]-1, blockData.index[i*8+1]-1, blockData.index[i*8+2]-1,//face1-背面
            // blockData.index[i*8]-1, blockData.index[i*8+2]-1, blockData.index[i*8+1]-1,//face1-正面
            
            //  /|
            // / |
            //----
            // blockData.index[i*8+1]-1, blockData.index[i*8+3]-1, blockData.index[i*8+2]-1,//face2-正面
            // blockData.index[i*8+1]-1, blockData.index[i*8+2]-1, blockData.index[i*8+3]-1,//face2-背面

            // ----
            // | /
            // |/
            // blockData.index[i*8+1]-1, blockData.index[i*8]-1, blockData.index[i*8+3]-1,//face3-坐标轴正方向上正面可视
            // blockData.index[i*8+1]-1, blockData.index[i*8+3]-1, blockData.index[i*8]-1,//face3-背面可视


            // blockData.index[i*8]-1, blockData.index[i*8+1]-1,blockData.index[i*8]-1,//010
            // blockData.index[i*8]-1, blockData.index[i*8+2]-1,blockData.index[i*8]-1,//020
            // blockData.index[i*8]-1, blockData.index[i*8+3]-1,blockData.index[i*8]-1,//030


            // NOTE：后四个顶点与前四个顶点位置一样
            // blockData.index[i*8+4]-1, blockData.index[i*8+4+1]-1, blockData.index[i*8+4]-1,//454
            // blockData.index[i*8+4]-1, blockData.index[i*8+4+2]-1, blockData.index[i*8+4]-1,//464
            // blockData.index[i*8+4]-1, blockData.index[i*8+4+3]-1, blockData.index[i*8+4]-1,//474

            // INFO:只有后四个点的索引，剩下一半索引并不使用，即索引为2289前的点并不采用
            blockData.index[i*8+4+1]-1, blockData.index[i*8+4+3]-1, blockData.index[i*8+4+2]-1,//face2-正面
            blockData.index[i*8+4+1]-1, blockData.index[i*8+4]-1, blockData.index[i*8+4+3]-1,//face3-正面
            
        );
    }

    return CreateGeometry(new Float32Array(vertexArray), new Uint16Array(indexArray));
}

function CreateGeometryFromPLTWithColor(blockData: { [key: string]: number[] }) {

    const scale = 1;
    // NOTE:仅X Y ZB点的数量与顶点一致
    let valueData = blockData.ZB.map(value => value * scale);

    // 计算最大值和最小值
    const minValue = Math.min(...valueData);
    const maxValue = Math.max(...valueData);
    // console.log(`valueData data, min:${minValue}, max:${maxValue}`);




    // 计算顶点的相对坐标
    const originPoint = [blockData.X[0], blockData.Y[0], blockData.ZB[0]];
    console.log("originPoint:", originPoint);

    // 颜色数组
    let colorArray = [];

    // 顶点数组
    let vertexArray = [];

    for (let i = 0; i < blockData.X.length; i++) {
        vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], blockData.ZB[i]-originPoint[2]);


        let depth = blockData.ZB[i] * scale;// 可与Tecplot中的PLT文件进行对比
        let color= Value2Color(depth,-202,141);

        colorArray.push(color[0],color[1],color[2]);
    }

    // 索引数组
    let indexArray = [];
    for (let i = 0; i < blockData.index.length / 8; i++) {
        // i为index每一行的内容

        // INFO：忽略PLT文件中具体的顶点组织方式，直接使用.顶点连接顺序应该存在问题
        indexArray.push(
            // blockData.index[i*8]-1, blockData.index[i*8+1]-1, blockData.index[i*8+2]-1,//face1-背面
            blockData.index[i*8+1]-1, blockData.index[i*8+3]-1, blockData.index[i*8+2]-1,//face1-正面

            blockData.index[i*8+1]-1, blockData.index[i*8+4]-1, blockData.index[i*8+3]-1,//face2-坐标轴正方向上正面可视
        );
    }

    return CreateGeometry(new Float32Array(vertexArray), new Uint16Array(indexArray));

    // return CreateGeometryWithColor(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(colorArray));
}


// INFO:读取一层PLT文件，构建五层的湖面模型。每层水面高度参考DAT文件，当前固定每层湖面高度先建模
function CreateFiveLevelGeometryFromPLT(blockData: { [key: string]: number[] }) {
    // 额外说明：当前不应该通过ZB+DEP/Z获取实际高程，而是应该通过ZB-DEP/Z的方式
// 1.读取PLT文件获取所有顶点，z值取自身的ZB(固定值22)，针对有数据的点（索引2290-4413）部分，额外加上DEP/Z，构建高低起伏的单层表面
// 1.plus 针对有数据的点（索引2290-4413）的点，使用DEP作为z值，其他点不考虑z值？(不妥当，会出现尖刺)需确定为什么不是每个出现的点的z值都改变了
// 2.武断的测试
// 2.1 五层数据均来自PLT文件。第一层正常取值 z值 = 22+DEP/Z；第二层取值 20 ；依次递减2m深度；构建五层的立体湖体模型
// 2.2 

// 用于测试，依旧只取前6个点，前两行索引数据

    const pointCount = blockData.X.length;
    console.log("pointCount is ",pointCount);

    let vertexArray = [];

    const originPoint = [blockData.X[0], blockData.Y[0], blockData.ZB[0]]
    console.log("originPoint:", originPoint);


    const refZValue = 22;

    // 顶点数组

    const scale = 100;//控制层间距的效果

    for(let j = 0;j < 5;j++){
        if(j == 4){//第j层需要单独处理，尽量使模型呈现的是突出的效果

            for (let i = 0; i < pointCount; i++) {
                if(i >= 2290 && i <= 4413){//2124个点，对应DAT文件中的点
                    vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 2 * j - blockData.DEP[i-2290]*10 )*scale);//可能会出现尖刺
                    
                    // INFO:通过添加随机数查看顶层或底层的z值变化
                    // var randomNumber = Math.floor(Math.random() * 11); // 生成0到10之间的随机整数
                    // vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 2 * j + randomNumber*1) * scale);//可能会出现尖刺
                }
                else
                    vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 2 * j)*scale);
            }
        }
        else{//其余四层仅改变顶点
            for (let i = 0; i < pointCount; i++) {
                vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 2 * j)*scale);
            }
        }

    }
    console.log("vertexArray length:", vertexArray.length / 3);



    // 索引数组
    let indexArray = [];
    
    const addIndex = 4;//控制取blockData前面4个点的索引还是后面4个点的索引
    for (let i = 0; i < blockData.index.length / 8; i++) {
    // for (let i = 0; i < 10; i++) {
        // i为index每一行的内容

        // 记录每层顶点之间的索引
        // NOTE:可以只做第一层和第五层的建模，即仅做顶面和底面的建模
        for(let j=0;j<5;j++){
            indexArray.push(
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex+3]-1 + pointCount*j, blockData.index[i*8+addIndex+2]-1 + pointCount*j,//face2-正面
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex]-1 + pointCount*j,   blockData.index[i*8+addIndex+3]-1 + pointCount*j,//face3-正面
            );

        }

        
        for(let j = 0;j < 5 - 1;j++){
            // let j=0;
            // 记录第j层和第j+1层之间的侧面
            indexArray.push(
                // 侧面1
                blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+2]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2' 2 3'
                blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+3]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2 3 3'
                // 侧面2
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+2]-1+pointCount*(j+1),//1 2 2'
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//1 2' 1'
                // 侧面3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1), blockData.index[i*8+addIndex+3]-1+pointCount*j,//0 3' 3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//0 0' 3'
                // 侧面4
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+1]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*j,//0 1' 1
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//0 0' 1'
            );
        }


    }

    

    return CreateGeometry(new Float32Array(vertexArray), new Uint16Array(indexArray));
}



// INFO:读取单层PLT文件，构建五层的湖面模型。读取五层DAT文件内容修改z值和顶点颜色
export function CreateFiveLevelGeometryFromPLTAndFiveLevelDAT(blockData: { [key: string]: number[] },hydroDataArray:HydrodynamicDataWithIndex[][]) {

    return CreateFiveLevelGeometryFromPLTAndFiveLevelDAT2(blockData, hydroDataArray, "temperature", 10, 21);

}

// 与上面的函数一样，只不过拓展了可选参数
export function CreateFiveLevelGeometryFromPLTAndFiveLevelDAT2(blockData: { [key: string]: number[] },dataArray:WaterDataWithIndex[][],valueName:string,valueMin:number,valueMax:number) {

    const pointCount = blockData.X.length;
    // console.log("pointCount is ",pointCount);
  
    let originPoint: number[] | null;
    if(blockData.Z.length == blockData.X.length)
        originPoint = [blockData.X[0], blockData.Y[0], blockData.Z[0]]
    else if(blockData.ZB.length == blockData.X.length)
        originPoint = [blockData.X[0], blockData.Y[0], blockData.ZB[0]]
    else{
        console.error("Can't find an attribute which can match count with X.");
    }
    // console.log("originPoint:", originPoint);

    // 先判断是否所有元素都是 什么水文类型 实例
    const isHydroDataArray = dataArray[0].every(item => item instanceof HydrodynamicDataWithIndex);
    const isWaterQulityDataArray = dataArray[0].every(item => item instanceof WaterQualityDataWithIndex);
    // console.log("isHydroDataArray:",isHydroDataArray);
    // console.log("isWaterQulityDataArray:",isWaterQulityDataArray);

    let refZValue = 20;//无值点的z值
    const scale = 1000;//控制层间距的效果

    // // INFO:输出${valueName}中最大值最小值
    // for (let index = 0; index < dataArray.length; index++) {
    //     const levelData = dataArray[index];
    //     console.log(`第${index}层数据${valueName}的值范围为：`);
    //     getHydroDataArrayMinMax(dataArray[index],valueName);
    // }


    // 顶点数组
    let vertexArray = [];

    // 顶点颜色
    let vertexColorArray = [];

    for(let j = 0;j < 5;j++){

        for (let i = 0; i < pointCount; i++) {
            if(i >= 2290 && i <= 4413){//2124个点，对应DAT文件中的点
                // vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (dataArray[j][i-2290].waterDepth - 2*j) * scale);//waterDepth - 2*j
                
                // 读取TIME_WQR中DAT文件的Z值数据，结合TEC_WQR中PLT文件X、Y来构建模型
                vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (dataArray[j][i-2290].Z) * scale);
                
                
                // FIXME:当数值变化很小时，指定分段的颜色将无法体现出来变化过程
                // let color = Value2ColorTenSegements(getValueFromNameHYDData(dataArray[j][i-2290],valueName),valueMin,valueMax);
                // console.log(`第${j}层数据中,${valueName}的值为${getValueFromNameHYDData(dataArray[j][i-2290],valueName)}`);
                if(isHydroDataArray){
                    let color = Value2Color(getValueFromNameHYDData(dataArray[j][i-2290],valueName),valueMin,valueMax,10);
                    vertexColorArray.push(color[0],color[1],color[2],1.0);//根据值转出来颜色，不透明
                }else if(isWaterQulityDataArray){
                    // FIXME:临时使用
                    // let color = Value2ColorBlueGreenYellowRedWithFixWQRValue(getValueFromNameWQRData(dataArray[j][i-2290],valueName));
                    // console.log("颜色为指定的定值");
                    let color = Value2Color(getValueFromNameWQRData(dataArray[j][i-2290],valueName),valueMin,valueMax,10);

                    vertexColorArray.push(color[0],color[1],color[2],1.0);
                }else{
                    console.log("Error: dataArray is not HydrodynamicDataWithIndex or WaterQualityDataWithIndex.");
                    vertexColorArray.push(1.0,1.0,1.0,1.0);//白色
                }


                
            }
            else{
                vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 1 * j) * scale);//无值处，顶点z值取 参考值 - 1 * levelcount
                
                vertexColorArray.push(1.0,1.0,1.0,0.0);//白色、全透明，将不显示
            }
        }
    }

    // console.log("vertexArray length:", vertexArray.length / 3);//4578*5
    // console.log("vertexColorArray length:", vertexColorArray.length / 4);//4578*5



    // 索引数组
    let indexArray = [];
    
    const addIndex = 4;//0; 控制取blockData前面4个点的索引(0) 还是后面4个点的索引(4)
    for (let i = 0; i < blockData.index.length / 8; i++) {
    // for (let i = 0; i < 10; i++) {//测试内容，只读入10行顶点索引数据
        // i为index每一行的内容

        // 记录每层顶点之间的索引
        // NOTE:可以只做第一层和第五层的建模，即仅做顶面和底面的建模
        for(let j=0;j<5;j++){
            // const j=4;
            indexArray.push(
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex+3]-1 + pointCount*j, blockData.index[i*8+addIndex+2]-1 + pointCount*j,//face2-正面
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex]-1 + pointCount*j,   blockData.index[i*8+addIndex+3]-1 + pointCount*j,//face3-正面
            );
        }

        
        for(let j = 0;j < 5 - 1;j++){
            // 记录第j层和第j+1层之间的侧面
            indexArray.push(
                // 侧面1
                blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+2]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2' 2 3'
                blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+3]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2 3 3'
                // 侧面2
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+2]-1+pointCount*(j+1),//1 2 2'
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//1 2' 1'
                // 侧面3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1), blockData.index[i*8+addIndex+3]-1+pointCount*j,//0 3' 3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//0 0' 3'
                // 侧面4
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+1]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*j,//0 1' 1
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//0 0' 1'
            );
        }


    }

    
    // return CreateGeometryWithColor(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(vertexColorArray));
    // 需注意材质Material需要设置参数transparent:true
    return CreateGeometryWithColor4(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(vertexColorArray));




function getValueFromNameHYDData(waterData:WaterDataWithIndex,valueName:string){
    if (waterData as HydrodynamicDataWithIndex) {
        const hydroData = waterData;
        switch(valueName){
            case "temperature":
                return hydroData.temperature;
                // break;
            case "salinity":
                return hydroData.salinity;
            case "USpeed":
                return hydroData.USpeed;
            case "VSpeed":
                return hydroData.VSpeed;
            case "waterDepth":
                return hydroData.waterDepth;
            case "waterLevel":
                return hydroData.waterLevel;
            case "flux":
                return hydroData.flux;
            case "layer":
                return hydroData.layer;
            case "Z":
                return hydroData.Z;
            default:
                console.error(`Your input content ${valueName} is not correct.`);
                return 0;
        }
    
    }else{
        console.error(`Your input content ${valueName} is not correct.`);
        return 0;
    }
    

}

function getValueFromNameWQRData(waterData:WaterDataWithIndex,valueName:string){
    if(waterData as WaterQualityDataWithIndex){
        // TODO:
        switch(valueName){
            case "layer":
                return waterData.layer;
            case "Z":
                return waterData.Z;
            case "NHX":
                return waterData.NHX;
            default:
                console.error(`Your input content ${valueName} is not correct.`);
                return 0;
        }
    }else{
        console.error(`Your input content ${valueName} is not correct.`);
        return 0;
    }
}


}



// INFO:读取单层PLT文件，构建五层的湖面模型。读取DAT文件内容修改z值和顶点颜色
export function CreateFiveLevelGeometryFromPLTAndDAT(blockData: { [key: string]: number[] },hydroDataArray:HydrodynamicDataWithIndex[]) {

    const pointCount = blockData.X.length;
    console.log("pointCount is ",pointCount);


    const originPoint = [blockData.X[0], blockData.Y[0], blockData.ZB[0]]
    console.log("originPoint:", originPoint);


    const refZValue = 22;//第一层z值

    // 顶点数组
    let vertexArray = [];

    const scale = 1000;//控制层间距的效果

    // 顶点颜色
    let vertexColorArray = [];

    // 计算最大值和最小值
    let valueData = [];
    hydroDataArray.forEach(element => {
        valueData.push(element.temperature);
    });
    const minValue = Math.min(...valueData);
    const maxValue = Math.max(...valueData);
    console.log(`valueData data, max:${maxValue},min:${minValue}`);


    for(let j = 0;j < 5;j++){

        for (let i = 0; i < pointCount; i++) {
            if(i >= 2290 && i <= 4413){//2124个点，对应DAT文件中的点
                // FIXME:解决无值点异常凸起问题
                // vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], (refZValue - 2 * j - hydroDataArray[i-2290].waterDepth *10 )*scale);
                vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], hydroDataArray[i-2290].waterDepth*scale);
                
                // TODO:当前为固定提取温度值进行渲染
                let color = Value2Color(hydroDataArray[i-2290].temperature,10,35);//value range:10-35
                vertexColorArray.push(color[0],color[1],color[2]);
                
            }
            else{
                vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1],0);// (refZValue - 2 * j)*scale);
                // vertexArray.push(blockData.X[i]-originPoint[0], blockData.Y[i]-originPoint[1], 0);
                
                vertexColorArray.push(1.0,1.0,1.0);//白色
            }
        }
    }


    console.log("vertexArray length:", vertexArray.length / 3);//4578*5
    console.log("vertexColorArray length:", vertexColorArray.length / 3);//4578*5



    // 索引数组
    let indexArray = [];
    
    const addIndex = 4;//控制取blockData前面4个点的索引还是后面4个点的索引
    for (let i = 0; i < blockData.index.length / 8; i++) {
    // for (let i = 0; i < 10; i++) {
        // i为index每一行的内容

        // 记录每层顶点之间的索引
        // NOTE:可以只做第一层和第五层的建模，即仅做顶面和底面的建模
        for(let j=0;j<5;j++){
            indexArray.push(
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex+3]-1 + pointCount*j, blockData.index[i*8+addIndex+2]-1 + pointCount*j,//face2-正面
                blockData.index[i*8+addIndex+1]-1 + pointCount*j, blockData.index[i*8+addIndex]-1 + pointCount*j,   blockData.index[i*8+addIndex+3]-1 + pointCount*j,//face3-正面
            );

        }

        
        for(let j = 0;j < 5 - 1;j++){
            // 记录第j层和第j+1层之间的侧面
            indexArray.push(
                // 侧面1
                blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+2]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2' 2 3'
                blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+3]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//2 3 3'
                // 侧面2
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*j,     blockData.index[i*8+addIndex+2]-1+pointCount*(j+1),//1 2 2'
                blockData.index[i*8+addIndex+1]-1+pointCount*j, blockData.index[i*8+addIndex+2]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//1 2' 1'
                // 侧面3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+3]-1+pointCount*(j+1), blockData.index[i*8+addIndex+3]-1+pointCount*j,//0 3' 3
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+3]-1+pointCount*(j+1),//0 0' 3'
                // 侧面4
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex+1]-1+pointCount*(j+1), blockData.index[i*8+addIndex+1]-1+pointCount*j,//0 1' 1
                blockData.index[i*8+addIndex]-1+pointCount*j, blockData.index[i*8+addIndex]-1+pointCount*(j+1),   blockData.index[i*8+addIndex+1]-1+pointCount*(j+1),//0 0' 1'
            );
        }


    }

    

    // return CreateGeometry(new Float32Array(vertexArray), new Uint16Array(indexArray));
    return CreateGeometryWithColor(new Float32Array(vertexArray), new Uint16Array(indexArray),new Float32Array(vertexColorArray));
}



export function getHydroDataArrayMinMax(waterDataArray:WaterDataWithIndex[],valueName:string){
    // 计算最大值和最小值
    let valueData:number[] = [];

    // 先判断是否所有元素都是 什么水文类型 实例
    const isHydroDataArray = waterDataArray.every(item => item instanceof HydrodynamicDataWithIndex);
    const isWaterQulityDataArray = waterDataArray.every(item => item instanceof WaterQualityDataWithIndex);
    console.log("isHydroDataArray:",isHydroDataArray);
    console.log("isWaterQulityDataArray:",isWaterQulityDataArray);

    if (isHydroDataArray) {
        const hydroDataArray = waterDataArray as HydrodynamicDataWithIndex[];
        switch (valueName) {
            case "temperature":
                hydroDataArray.forEach(element => {
                    valueData.push(element.temperature);
                });
                break;
            case "waterLevel":
                hydroDataArray.forEach(element => {
                    valueData.push(element.waterLevel);
                });
                break;
            case "waterDepth":
                hydroDataArray.forEach(element => {
                    valueData.push(element.waterDepth);
                });
                break;
            case "Z":
                hydroDataArray.forEach(element => {
                    valueData.push(element.Z);
                });
                break;
            default:
                break;
        }
    }else if(isWaterQulityDataArray){
        const waterQulityDataArray = waterDataArray as WaterQualityDataWithIndex[];
        switch (valueName) {
            case "Z":
                waterQulityDataArray.forEach(element => {
                    valueData.push(element.Z);
                });
                break;
            case "NHX":
                waterQulityDataArray.forEach(element => {
                    valueData.push(element.NHX);
                });
                break;
            default:
                break;
        }
    }else{
        console.error(`Your input content ${valueName} is not correct.`);
    }
    

    const minValue = Math.min(...valueData);
    const maxValue = Math.max(...valueData);
    console.log(`${valueName} data ,min:${minValue}, max:${maxValue}`);
    return valueData;
}

